//package com.bsj.power.system.config.monitor;
//
//import com.bsj.power.common.config.cached.RedisCached;
//import com.bsj.power.common.config.redis.RedisConstant;
//import com.bsj.power.common.config.rocketmq.producer.BaseMqPushUtil;
//import com.bsj.power.common.constant.MqTopicAndTagConstants;
//import com.bsj.power.common.constant.NumericalConstants;
//import com.bsj.power.common.def.dto.AlertDTO;
//import com.bsj.power.common.def.entity.log.SysExceptionLog;
//import com.bsj.power.common.def.enums.ServerMonitorAlertEnum;
//import com.bsj.power.common.def.vo.WebSocketMsgVO;
//import com.bsj.power.common.mapper.SysExceptionLogMapper;
//import com.bsj.power.common.util.ExceptionUtil;
//import com.bsj.power.common.util.HttpUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Component;
//
//import java.util.Date;
//import java.util.HashMap;
//import java.util.Map;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.alibaba.fastjson.JSONArray;
//
//import javax.annotation.Resource;
//
///**
// * 监控
// */
//@Slf4j
//@Component
//public class ServerMonitor {
//
//    @Value("${prometheus.greptimedb}")
//    public String greptimedb;
//
//    @Value("${prometheus.db}")
//    public String db;
//
//    @Value("${prometheus.username}")
//    public String username;
//
//    @Value("${prometheus.password}")
//    public String password;
//
//    @Autowired
//    private BaseMqPushUtil baseMqPushUtil;
//
//    @Autowired
//    private RedisCached redisCached;
//
//    @Resource
//    private SysExceptionLogMapper exceptionLogMapper;
//
//
//    /**
//     * 存储每个主机的告警状态
//     */
//    private static final Map<String, Long> HOST_ALERT_TIMES = new HashMap<>();
//
//    /**
//     * 启动报警监控
//     */
//    public void startAlertMonitor() {
//        // 使用线程启动
//        new Thread(() -> {
//            while (true) {
//                checkResourceUsage();
//                try {
//                    Thread.sleep(60000); // 每分钟检查一次
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }, "ServerMonitorThread").start();
//    }
//
//    /**
//     * 检查资源使用率
//     */
//    private void checkResourceUsage() {
//        try {
//            checkCpuUsage();
//            checkMemUsage();
//            checkDiskUsage();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    /**
//     * CPU
//     */
//    private void checkCpuUsage() {
//        queryAndCheckUsage("cpu_usage_user", ServerMonitorAlertEnum.CPU);
//    }
//
//    /**
//     * 内存
//     */
//    private void checkMemUsage() {
//        queryAndCheckUsage("mem_used_percent", ServerMonitorAlertEnum.MEMORY);
//    }
//
//    /**
//     * 硬盘
//     */
//    private void checkDiskUsage() {
//        queryAndCheckUsage("disk_used_percent", ServerMonitorAlertEnum.DISK);
//    }
//
//    /**
//     * 查询资源使用率
//     *
//     * @param table                  查询表名称
//     * @param serverMonitorAlertEnum 告警类型枚举
//     */
//    private void queryAndCheckUsage(String table, ServerMonitorAlertEnum serverMonitorAlertEnum) {
//        try {
//            /**
//             * GreptimeDB 提供了 HTTP API 用于与数据库进行交互。
//             */
//            String path = "/v1/sql?db=";
//            String url = greptimedb + path + db;
//            String body = String.format("sql=SELECT DISTINCT ON (agent_hostname) agent_hostname, greptime_value FROM %s WHERE greptime_timestamp > (now() - INTERVAL '1 minute') ORDER BY agent_hostname, greptime_timestamp DESC;", table);
//            String jsonResponse = HttpUtil.doPostAuth(url, body, username, password);
//            JSONObject json = JSON.parseObject(jsonResponse);
//            JSONArray results = json.getJSONArray("output");
//            if (results != null && results.size() > 0) {
//                JSONObject firstResult = results.getJSONObject(0);
//                JSONObject records = firstResult.getJSONObject("records");
//                if (records != null) {
//                    JSONArray rows = records.getJSONArray("rows");
//                    if (rows != null && rows.size() > 0) {
//                        for (Object result : rows) {
//                            JSONArray valueArray = (JSONArray) result;
//                            String host = valueArray.getString(0);
//                            double usage = valueArray.getDouble(1);
//                            AlertDTO alertDTO = checkIsPushAlarm(serverMonitorAlertEnum, usage);
//                            if (alertDTO.getFlag()) {
//                                updateHostAlertTime(host, usage, alertDTO.getValue(), serverMonitorAlertEnum);
//                            } else {
//                                resetHostAlertTime(host, serverMonitorAlertEnum);
//                            }
//                        }
//                    }
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    /**
//     * 检查是否持续5分钟，并更新告警状态，推送告警通知
//     *
//     * @param host
//     * @param usage
//     * @param sysSetValue
//     * @param serverMonitorAlertEnum
//     */
//    private void updateHostAlertTime(String host, double usage, int sysSetValue, ServerMonitorAlertEnum serverMonitorAlertEnum) {
//        long currentTime = System.currentTimeMillis();
//        String key = host + ":" + serverMonitorAlertEnum.getAlertType();
//        Long alertTime = HOST_ALERT_TIMES.get(key);
//        if (alertTime != null) {
//            if (currentTime - alertTime >= 60 * 1000) {
//                // 记录告警日志并推送消息
//                saveAndSendAlarm(host, usage, sysSetValue, serverMonitorAlertEnum);
//                // 重置计时器
//                resetHostAlertTime(host, serverMonitorAlertEnum);
//            }
//        } else {
//            HOST_ALERT_TIMES.put(key, currentTime);
//        }
//    }
//
//    /**
//     * 重置告警时间
//     *
//     * @param host
//     * @param serverMonitorAlertEnum
//     */
//    private void resetHostAlertTime(String host, ServerMonitorAlertEnum serverMonitorAlertEnum) {
//        String key = host + ":" + serverMonitorAlertEnum.getAlertType();
//        HOST_ALERT_TIMES.remove(key);
//    }
//
//    /**
//     * 检查是否推送报警
//     *
//     * @param serverMonitorAlertEnum 报警类型
//     * @param value                  资源使用率
//     * @return
//     */
//    private AlertDTO checkIsPushAlarm(ServerMonitorAlertEnum serverMonitorAlertEnum, double value) {
//        AlertDTO alertDTO = new AlertDTO();
//        boolean flag = false;
//        // 服务器报警通知阀值未设置的时候，初始值为80
//        int systemSetValue = 80;
//        switch (serverMonitorAlertEnum) {
//            case CPU:
//                String cpuValueStr = redisCached.get(RedisConstant.SYS_CPU_THRESHOLD);
//                if (cpuValueStr != null) {
//                    systemSetValue = Integer.parseInt(cpuValueStr);
//                }
//                break;
//            case MEMORY:
//                String memoryValueStr = redisCached.get(RedisConstant.SYS_MEMORY_THRESHOLD);
//                if (memoryValueStr != null) {
//                    systemSetValue = Integer.parseInt(memoryValueStr);
//                }
//                break;
//            case DISK:
//                String diskValueStr = redisCached.get(RedisConstant.SYS_DISK_THRESHOLD);
//                if (diskValueStr != null) {
//                    systemSetValue = Integer.parseInt(diskValueStr);
//                }
//                break;
//            default:
//                break;
//        }
//        // 如果超过系统设置的报警阀值，则记录并推送报警通知
//        if (value >= systemSetValue) {
//            flag = true;
//        }
//        alertDTO.setFlag(flag);
//        alertDTO.setValue(systemSetValue);
//        return alertDTO;
//    }
//
//    /**
//     * 发送并保存告警通知
//     *
//     * @param host
//     * @param usage
//     * @param sysSetValue
//     * @param serverMonitorAlertEnum
//     */
//    private void saveAndSendAlarm(String host, double usage, int sysSetValue, ServerMonitorAlertEnum serverMonitorAlertEnum) {
//        // 服务器异常记录
//        SysExceptionLog exceptionLog = new SysExceptionLog();
//        // 服务器报警名称
//        exceptionLog.setName(ServerMonitorAlertEnum.getByValue(serverMonitorAlertEnum.getAlertType()));
//        // 服务器实例名称
//        int index = host.indexOf(":");
//        if (index != -1) {
//            String ip = host.substring(0, index);
//            // 服务IP地址
//            exceptionLog.setIp(ip);
//        } else {
//            exceptionLog.setIp(host);
//        }
//        // 服务器异常类型
//        exceptionLog.setExceptionType(serverMonitorAlertEnum.getAlertType());
//        // 服务器异常内容
//        exceptionLog.setContent("主机：" + host + "，" + exceptionLog.getName() + "，超过告警阈值设置:" + sysSetValue + "%，当前使用率：" + String.format("%.2f", usage) + "%");
//        exceptionLog.setCreateTime(new Date());
//        // 保存成功
//        if (exceptionLogMapper.insert(exceptionLog) > 0) {
//            try {
//                WebSocketMsgVO webSocketMsgVO = WebSocketMsgVO.builder()
//                        .msgType(NumericalConstants.FOUR)
//                        .obj(exceptionLog)
//                        .build();
//                baseMqPushUtil.sendTopicBytes(MqTopicAndTagConstants.SYSTEM_WEB_SERVER_CHANGE_TOPIC,
//                        MqTopicAndTagConstants.SYSTEM_WEB_PRODUCT_CHANGE_TAG, JSON.toJSONBytes(webSocketMsgVO));
//            } catch (Exception e) {
//                log.error("推送服务器异常错误：{}", ExceptionUtil.getStackStr(e));
//            }
//        }
//    }
//}
